#include <rtthread.h>
#include <dfs_posix.h>
#include <rtdevice.h>
#include <string.h>
#include "board.h"

static rt_device_t ply_device;

#define BUFF_SIZE 320
static uint8_t buffer[BUFF_SIZE];

static int spk_config(const char *device, int samplerate, int channels, int vol)
{
    rt_err_t result = RT_EOK;
    struct rt_audio_caps caps;

//    printf("device %s samplerate %d channels %d vol %d\n", device, samplerate, channels, vol);

    ply_device = rt_device_find(device);
    if (ply_device == RT_NULL)
    {
        printf("device %s not find", device);
        return -RT_ERROR;
    }

    caps.main_type = AUDIO_TYPE_OUTPUT;
    caps.sub_type = AUDIO_DSP_PARAM;
    caps.udata.config.samplerate = samplerate;
    caps.udata.config.channels = channels;
    caps.udata.config.samplebits = 16;
    result = rt_device_control(ply_device, AUDIO_CTL_CONFIGURE, &caps);
    if (result != RT_EOK)
    {
        printf("control %s device faield", device);
        return -RT_ERROR;
    }

    caps.main_type = AUDIO_TYPE_MIXER;
    caps.sub_type = AUDIO_MIXER_VOLUME;
    caps.udata.value = vol; //SPEAK VOL
    result = rt_device_control(ply_device, AUDIO_CTL_CONFIGURE, &caps);
    if (result != RT_EOK)
    {
        printf("control %s device faield", device);
        return -RT_ERROR;
    }

    result = rt_device_open(ply_device, RT_DEVICE_OFLAG_WRONLY);
    if (result != RT_EOK)
    {
        printf("open %s device faield", device);
        return -RT_ERROR;
    }
    printf("spk config success\n");

    return RT_EOK;
}

static rt_device_t rec_device;

static int mic_config(const char *device, int samplerate, int channels, int vol)
{
    rt_err_t result = RT_EOK;
    struct rt_audio_caps caps;

    rec_device = rt_device_find(device);
    if (rec_device == RT_NULL)
    {
        printf("device %s not find", device);
        return -RT_ERROR;
    }

    caps.main_type = AUDIO_TYPE_INPUT;
    caps.sub_type = AUDIO_DSP_PARAM;
    caps.udata.config.samplerate = samplerate;
    caps.udata.config.channels = channels;
    // caps.udata.config.mic_en = mic_en;
    caps.udata.config.samplebits = 16;
    result = rt_device_control(rec_device, AUDIO_CTL_CONFIGURE, &caps);
    if (result != RT_EOK)
    {
        printf("control %s device faield", device);
        return -RT_ERROR;
    }

    caps.main_type = AUDIO_TYPE_MIXER;
    caps.sub_type = AUDIO_MIXER_VOLUME;
    caps.udata.value = vol;
    result = rt_device_control(rec_device, AUDIO_CTL_CONFIGURE, &caps);
    if (result != RT_EOK)
    {
        printf("control %s device faield", device);
        return -RT_ERROR;
    }

    result = rt_device_open(rec_device, RT_DEVICE_OFLAG_RDONLY);
    if (result != RT_EOK)
    {
        printf("open %s device faield", device);
        return -RT_ERROR;
    }

    printf("mic config success\n");
//    rt_device_read(rec_device, 0, buffer, BUFF_SIZE);
    return RT_EOK;
}

static int soft_loopback(int argc, char *argv[])
{
    printf("**************LOOP BACK***************\n");

    int res;
    int amplerate = 16000;
    if(argv[1])
        amplerate = atoi(argv[1]);
    int ch = 1;
    if(argv[2])
        ch = atoi(argv[2]);
    int vol = 80;
    if(argv[3])
        vol = atoi(argv[3]);

    res = spk_config("speak0", amplerate, ch, vol);
    if (res != RT_EOK)
    {
        goto ERROR1;
    }

    res = mic_config("mic0", amplerate, ch, vol);
    if (res != RT_EOK)
    {
        goto ERROR1;
    }


    while(1)
    {
        rt_device_read(rec_device, 0, buffer, BUFF_SIZE);
        rt_device_write(ply_device, 0, buffer, BUFF_SIZE);
    }

    rt_device_close(ply_device);

ERROR1:
    return -RT_ERROR;
}
MSH_CMD_EXPORT(soft_loopback, soft loopback); //recode_audio 16000 1


